﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Windows;
using System.Threading.Tasks;
using JiveMessenger.Network;
using JmShared;
using System.Collections.ObjectModel;
using JiveMessenger.Utilities;
using Windows.UI.Xaml.Media;
using Windows.UI;
using Windows.UI.Text;
using System.Runtime.Serialization;


namespace JiveMessenger.Models
{
    [DataContract]
    public class JiveContactModel : INotifyPropertyChanged, IComparable<IContact>, IEquatable<IContact>, IContact
    {
        public static readonly JiveContactModel GreenText = new JiveContactModel("1", "GreenText@Jive.com", "GreenText", DeviceType.PC) { FontColor = Colors.Green, FontStyle = FontStyle.Normal, FontFamily = new FontFamily("Segoe UI"), FontWeight = FontWeights.Normal };
        public static readonly JiveContactModel RedText = new JiveContactModel("2", "RedText@Jive.com", "RedText", DeviceType.PC) { FontColor = Colors.Maroon, FontStyle = FontStyle.Normal, FontFamily = new FontFamily("Segoe UI"), FontWeight = FontWeights.Normal };
        public static readonly JiveContactModel GrayText = new JiveContactModel("3", "GrayText@Jive.com", "GrayText", DeviceType.PC) { FontColor = Colors.DimGray, FontStyle = FontStyle.Normal, FontFamily = new FontFamily("Segoe UI"), FontWeight = FontWeights.Normal };
        [DataMember]
        public string UserName { get; set; }
        public string UserID
        {
            get
            {
                return this.UserName + "#" + this.DeviceID;
            }
        }
        [DataMember]
        public string DeviceID { get; set; }

        public object Instance
        {
            get { return this; }
        }
        /// <summary>
        /// Returns the Nickname if available, else the Username
        /// </summary>
        public string PrettyName
        {
            get
            {
                return !String.IsNullOrEmpty(this.NickName) ? this.NickName : this.UserName;
            }
        }

        private string _nickName;
        [DataMember]
        public string NickName
        {
            get { return _nickName; }
            set
            {
                if (value != this._nickName)
                {
                    this._nickName = value;
                    RaisePropertyChanged("NickName");
                    RaisePropertyChanged("PrettyName");
                }
            }
        }

        private ClientStatus _clientStatus;
        public ClientStatus ClientStatus
        {
            get { return _clientStatus; }
            set
            {
                if (_clientStatus != value)
                {
                    _clientStatus = value;
                    RaisePropertyChanged("ClientStatus");
                }
            }
        }
        private DeviceType _deviceType;
        [DataMember]
        public DeviceType DeviceType
        {
            get { return _deviceType; }
            set
            {
                if (_deviceType != value)
                {
                    _deviceType = value;
                    RaisePropertyChanged("DeviceType");
                }
            }
        }


        private DateTime _afkStart;
        public DateTime AfkStart
        {
            get { return _afkStart; }
            set
            {
                if (_afkStart != value)
                {
                    _afkStart = value;
                    RaisePropertyChanged("AfkStart");
                }
            }
        }

        private DateTime _offlineStart;
        public DateTime OfflineStart
        {
            get { return _offlineStart; }
            set
            {
                if (_offlineStart != value)
                {
                    _offlineStart = value;
                    RaisePropertyChanged("OfflineStart");
                }
            }
        }




        private int _unreadMessageCount;
        [DataMember]
        public int UnreadMessageCount
        {
            get { return _unreadMessageCount; }
            set
            {
                if (value != this._unreadMessageCount)
                {
                    this._unreadMessageCount = value;
                    RaisePropertyChanged("UnreadMessageCount");
                }
            }
        }


        //private string _pmStatus;
        //public string PmStatus
        //{
        //    get { return _pmStatus; }
        //    set
        //    {
        //        if (value != this._pmStatus)
        //        {
        //            this._pmStatus = value;
        //            RaisePropertyChanged("PmStatus");
        //        }
        //    }
        //}

        public string ToolTipText
        {
            get
            {
                string text = this.UserName;
                if (this.ClientStatus == JmShared.ClientStatus.Afk && this.AfkStart != DateTime.MinValue)
                    text += string.Format(" - AFK for {0}", DateTime.Now.Subtract(this.AfkStart).ToFormattedString());
                else if (this.ClientStatus == JmShared.ClientStatus.Offline && this.OfflineStart != DateTime.MinValue)
                    text += string.Format(" - Offline for {0}", DateTime.Now.Subtract(this.OfflineStart).ToFormattedString());
                return text;
            }
        }

        private ObservableCollection<IChatGroup> _chatGroups;
        public ObservableCollection<IChatGroup> ChatGroups
        {
            get { return _chatGroups; }
            set
            {
                if (_chatGroups != value)
                {
                    _chatGroups = value;
                    RaisePropertyChanged("ChatGroups");
                }
            }
        }

        private ObservableCollection<JiveCustomEmoticonModel> _customEmoticons;
        [DataMember]
        public ObservableCollection<JiveCustomEmoticonModel> CustomEmoticons
        {
            get { return _customEmoticons; }
            set
            {
                if (_customEmoticons != value)
                {
                    _customEmoticons = value;
                    RaisePropertyChanged("CustomEmoticons");
                }
            }
        }

        private ObservableCollection<IEmoticon> _recentlyUsedEmoticons;
        [DataMember]
        public ObservableCollection<IEmoticon> RecentlyUsedEmoticons
        {
            get { return _recentlyUsedEmoticons; }
            set
            {
                if (_recentlyUsedEmoticons != value)
                {
                    _recentlyUsedEmoticons = value;
                    RaisePropertyChanged("RecentlyUsedEmoticons");
                }
            }
        }




        private bool _isIgnored;
        [DataMember]
        public bool IsIgnored
        {
            get { return _isIgnored; }
            set
            {
                if (_isIgnored != value)
                {
                    _isIgnored = value;
                    RaisePropertyChanged("IsIgnored");
                }
            }
        }


        private string _avatar;
        [DataMember]
        public string Avatar
        {
            get { return _avatar; }
            set
            {
                if (_avatar != value)
                {
                    _avatar = value;
                    RaisePropertyChanged("Avatar");
                }
            }
        }

        private FontFamily _fontFamily;

        public FontFamily FontFamily
        {
            get
            {
                if (_fontFamily == null)
                {
                    _fontFamily = new FontFamily("Segoe UI");
                }
                return _fontFamily;
            }
            set
            {
                if (_fontFamily != value)
                {
                    _fontFamily = value;
                    RaisePropertyChanged("FontFamily");
                }
            }
        }

        private FontWeight _fontWeight;
        [DataMember]
        public FontWeight FontWeight
        {
            get { return _fontWeight; }
            set
            {
                if (!_fontWeight.Equals(value))
                {
                    _fontWeight = value;
                    RaisePropertyChanged("FontWeight");
                }
            }
        }

        private FontStyle _fontStyle;
        [DataMember]
        public FontStyle FontStyle
        {
            get { return _fontStyle; }
            set
            {
                if (_fontStyle != value)
                {
                    _fontStyle = value;
                    RaisePropertyChanged("FontStyle");
                }
            }
        }

        private double _fontSize;
        [DataMember]
        public double FontSize
        {
            get { return _fontSize; }
            set
            {
                if (_fontSize != value)
                {
                    _fontSize = value;
                    RaisePropertyChanged("FontSize");
                }
            }
        }

        private Color _fontColor;
        [DataMember]
        public Color FontColor
        {
            get { return _fontColor; }
            set
            {
                if (_fontColor != value)
                {
                    _fontColor = value;
                    RaisePropertyChanged("FontColor");
                }
            }
        }

        private bool _isFriend;
        [DataMember]
        public bool IsFriend
        {
            get { return _isFriend; }
            set
            {
                if (_isFriend != value)
                {
                    _isFriend = value;
                    RaisePropertyChanged("IsGroupContact");
                }
            }
        }

        private bool _showInContactList;
        [DataMember]
        public bool ShowInContactList
        {
            get { return _showInContactList; }
            set
            {
                if (_showInContactList != value)
                {
                    _showInContactList = value;
                    RaisePropertyChanged("ShowInContactList");
                }
            }
        }



        public JiveContactModel(string deviceID, string username, string nickName, DeviceType deviceType, bool isFriend = true)
        {
            this.DeviceID = deviceID;
            this.UserName = username;
            this.NickName = nickName;
            this.ClientStatus = JmShared.ClientStatus.Available;
            this.ChatGroups = new ObservableCollection<IChatGroup>();
            this.IsFriend = isFriend;
            this.CustomEmoticons = new ObservableCollection<JiveCustomEmoticonModel>();
            this.RecentlyUsedEmoticons = new ObservableCollection<IEmoticon>();
        }
        public JiveContactModel()
        {
        }
        [OnDeserialized]
        internal void Initialize(StreamingContext context)
        {
            this.ChatGroups = new ObservableCollection<IChatGroup>();
            //this.CustomEmoticons = new ObservableCollection<JiveCustomEmoticonModel>();
            //this.RecentlyUsedEmoticons = new ObservableCollection<IEmoticon>();
        }
        public static JiveContactModel CreatePlaceholderUser(string userID)
        {
            var deviceType = SharedStaticMethods.GetDeviceType(userID);
            string deviceID = userID.Substring(userID.IndexOf("#"));
            string username = userID.Substring(0, userID.IndexOf("#"));
            JiveContactModel model = new JiveContactModel(deviceID, username, "", deviceType);
            model.FontSize = 14;
            model.FontColor = Colors.Gray;
            return model;
        }
        public override int GetHashCode()
        {
            return this.UserID.GetHashCode();
        }

        public override bool Equals(object obj)
        {
            return Equals(obj as IContact);
        }
        public bool Equals(IContact other)
        {
            if (other == null)
                return false;
            return this.UserID == other.UserID;
        }
        public int CompareTo(IContact other)
        {
            if (this.PrettyName == other.PrettyName)
                return 0;

            int n = this.PrettyName.CompareTo(other.PrettyName);
            return n;
        }

        protected void RaisePropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }
        public event PropertyChangedEventHandler PropertyChanged;

        public IContact Clone()
        {
            JiveContactModel model = new JiveContactModel()
            {
                AfkStart = this.AfkStart,
                Avatar = this.Avatar,
                ChatGroups = new ObservableCollection<IChatGroup>(this.ChatGroups),
                ClientStatus = this.ClientStatus,
                CustomEmoticons = new ObservableCollection<JiveCustomEmoticonModel>(this.CustomEmoticons),
                DeviceID = this.DeviceID,
                DeviceType = this.DeviceType,
                FontColor = this.FontColor,
                FontFamily = this.FontFamily,
                FontSize = this.FontSize,
                FontStyle = this.FontStyle,
                FontWeight = this.FontWeight,
                IsFriend = this.IsFriend,
                IsIgnored = this.IsIgnored,
                NickName = this.NickName,
                RecentlyUsedEmoticons = new ObservableCollection<IEmoticon>(this.RecentlyUsedEmoticons),
                OfflineStart = this.OfflineStart,
                ShowInContactList = this.ShowInContactList,
                UnreadMessageCount = this.UnreadMessageCount,
                UserName = this.UserName
            };
            return model;
        }


    }

}
